/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(
    dead_code,
    mutable_transmutes,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut,
    unused_variables,
    unreachable_code,
    clippy::never_loop,
    clippy::if_same_then_else,
    clippy::too_many_arguments
)]

pub const IMPLIED: libc::c_int = 2;
pub const UNSPEC: libc::c_int = -1;
pub const COMMAND: libc::c_int = 257;
pub const SUDO_DIGEST_SHA224: libc::c_int = 0;
pub const SUDO_DIGEST_SHA256: libc::c_int = 1;
pub const SUDO_DIGEST_SHA384: libc::c_int = 2;
pub const SUDO_DIGEST_SHA512: libc::c_int = 3;
pub const SUDO_DIGEST_INVALID: libc::c_int = 4;
//use crate::alias::cmndspec_list;

//use crate::alias::cmndtag;
use crate::common::*;
//use crate::alias::privilege;

extern "C" {
    static mut sudoers_subsystem_ids: [libc::c_uint; 0];
    fn digest_type_to_name(digest_type: libc::c_int) -> *const libc::c_char;

    fn strndup(_: *const libc::c_char, _: libc::c_ulong) -> *mut libc::c_char;
    fn free_privilege(priv_0: *mut privilege);
    fn strpbrk(_: *const libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
    fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
    fn sudo_debug_printf2_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        level: libc::c_int,
        fmt: *const libc::c_char,
        _: ...
    );
    fn snprintf(
        _: *mut libc::c_char,
        _: libc::c_ulong,
        _: *const libc::c_char,
        _: ...
    ) -> libc::c_int;

    fn sudoers_defaults_to_tags(
        var: *const libc::c_char,
        val: *const libc::c_char,
        op: libc::c_int,
        tags: *mut cmndtag,
    ) -> bool;
    fn rcstr_delref(s: *const libc::c_char);
    fn parse_timeout(timestr: *const libc::c_char) -> libc::c_int;
    fn rcstr_alloc(len: size_t) -> *mut libc::c_char;
    fn parse_gentime(expstr: *const libc::c_char) -> time_t;
    fn sudo_warnx_nodebug_v1(fmt: *const libc::c_char, _: ...);
    fn __ctype_b_loc() -> *mut *const libc::c_ushort;
    fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
    fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
    fn free_members(members: *mut member_list);
    fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
    fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
    fn inet_pton(
        __af: libc::c_int,
        __cp: *const libc::c_char,
        __buf: *mut libc::c_void,
    ) -> libc::c_int;
    fn rcstr_addref(s: *const libc::c_char) -> *mut libc::c_char;

}

pub type in_addr_t = uint32_t;
pub type uint32_t = __uint32_t;
pub type __uint32_t = libc::c_uint;
pub type uint16_t = libc::c_ushort;

pub const _ISblank: libc::c_int = 2;
pub const AF_INET: libc::c_int = 2;
pub const AF_INET6: libc::c_int = 10;
pub const MYSELF: libc::c_int = 298;
pub const ALL: libc::c_short = 284;
pub const DEFAULTS: libc::c_short = 265;

pub type sudo_ldap_iter_t =
    Option<unsafe extern "C" fn(*mut *mut libc::c_void) -> *mut libc::c_char>;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct in6_addr {
    pub __in6_u: in6_mid,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec_list {
    pub tqh_first: *mut cmndspec,
    pub tqh_last: *mut *mut cmndspec,
}
/*
#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec {
    pub entries: cmndspec_midd,
    pub runasuserlist: *mut member_list,
    pub runasgrouplist: *mut member_list,
    pub cmnd: *mut member,
    pub tags: cmndtag,
    pub timeout: libc::c_int,
    pub notbefore: time_t,
    pub notafter: time_t,
    pub role: *mut libc::c_char,
    pub type_0: *mut libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec_midd {
    pub tqe_next: *mut cmndspec,
    pub tqe_prev: *mut *mut cmndspec,
}
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub union in6_mid {
    pub __u6_addr8: [uint8_t; 16],
    pub __u6_addr16: [uint16_t; 8],
    pub __u6_addr32: [uint32_t; 4],
}

#[derive(Copy, Clone)]
#[repr(C)]
pub union sudo_in_addr_un {
    pub ip4: in_addr,
    pub ip6: in6_addr,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct in_addr {
    pub s_addr: in_addr_t,
}

#[no_mangle]
pub fn sudo_ldap_is_negated(mut valp: *mut *mut libc::c_char) -> bool {
    unsafe {
        let mut val: *mut libc::c_char = *valp;
        let mut ret: bool = 0 as libc::c_int != 0;
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        while *val as libc::c_int == '!' as i32 {
            ret = !ret;
            loop {
                val = val.offset(1);

                if *(*__ctype_b_loc()).offset(*val as libc::c_uchar as libc::c_int as isize)
                    as libc::c_int
                    & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                    == 0
                /*if !(*(*__ctype_b_loc()).offset(*val as libc::c_uchar as libc::c_int as isize)
                as libc::c_int
                & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                != 0)*/
                {
                    break;
                }
            }
        }
        *valp = val;
        debug_return_bool!(ret);
    } //unsafe
}

#[no_mangle]
pub fn sudo_ldap_parse_option(
    mut optstr: *mut libc::c_char,
    mut varp: *mut *mut libc::c_char,
    mut valp: *mut *mut libc::c_char,
) -> libc::c_int {
    let mut cp: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut val: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut var: *mut libc::c_char = optstr;
    let mut op: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        cp = strchr(var, '=' as i32);
        if cp > var {
            val = cp.offset(1 as libc::c_int as isize);
            op = *cp.offset(-(1 as libc::c_int) as isize) as libc::c_int;
            if op == '+' as i32 || op == '-' as i32 {
                cp = cp.offset(-1);
            } else {
                op = 1 as libc::c_int;
            }
            while cp > var
                && *(*__ctype_b_loc()).offset(*cp.offset(-(1 as libc::c_int) as isize)
                    as libc::c_uchar as libc::c_int
                    as isize) as libc::c_int
                    & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                    != 0
            {
                cp = cp.offset(-1);
            }
            *cp = '\u{0}' as i32 as libc::c_char;
            while *(*__ctype_b_loc()).offset(*val as libc::c_uchar as libc::c_int as isize)
                as libc::c_int
                & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                != 0
            {
                val = val.offset(1);
            }
            if *val as libc::c_int == '"' as i32 {
                let mut ep: *mut libc::c_char = val.offset(strlen(val) as isize);
                if ep != val
                    && *ep.offset(-(1 as libc::c_int) as isize) as libc::c_int == '"' as i32
                {
                    val = val.offset(1);
                    *ep.offset(-(1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char;
                }
            }
        } else {
            op = if sudo_ldap_is_negated(&mut var) as libc::c_int != 0 {
                0 as libc::c_int
            } else {
                1 as libc::c_int
            };
        }
        *varp = var;
        *valp = val;

        debug_return_int!(op);
    } //unsafe
}

fn array_to_member_list(mut a: *mut libc::c_void, mut iter: sudo_ldap_iter_t) -> *mut member_list {
    let mut negated_members: member_list = member_list {
        tqh_first: std::ptr::null_mut::<member>(),
        tqh_last: std::ptr::null_mut::<*mut member>(),
    };
    negated_members = {
        member_list {
            tqh_first: std::ptr::null_mut::<member>(),
            tqh_last: &mut negated_members.tqh_first,
        }
        //init
    };
    let mut members: *mut member_list = std::ptr::null_mut::<member_list>();
    let mut m: *mut member = std::ptr::null_mut::<member>();
    let mut val: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    //let sudo_debug_subsys: libc::c_int = *sudoers_subsystem_ids
    //    .as_mut_ptr()
    //    .offset(6 as libc::c_int as isize) as libc::c_int;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        members = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<member_list>() as libc::c_ulong,
        ) as *mut member_list;
        if members.is_null() {
            return std::ptr::null_mut::<member_list>();
        }

        (*members).tqh_first = std::ptr::null_mut::<member>();
        (*members).tqh_last = &mut (*members).tqh_first;

        'bad: loop {
            loop {
                val = iter.expect("non-null function pointer")(&mut a);
                if val.is_null() {
                    break;
                }

                m = calloc(
                    1 as libc::c_int as libc::c_ulong,
                    ::std::mem::size_of::<member>() as libc::c_ulong,
                ) as *mut member;
                if m.is_null() {
                    break 'bad;
                }
                (*m).negated = sudo_ldap_is_negated(&mut val) as libc::c_short;

                match *val.offset(0 as libc::c_int as isize) as u8 as char {
                    '\0' => (*m).type0 = MYSELF as libc::c_short,
                    '+' => {
                        (*m).type0 = NETGROUP as libc::c_short;
                        (*m).name = strdup(val);
                        if ((*m).name).is_null() {
                            free(m as *mut libc::c_void);
                            break 'bad;
                        }
                    }
                    '%' => {
                        (*m).type0 = USERGROUP as libc::c_short;
                        (*m).name = strdup(val);
                        if ((*m).name).is_null() {
                            free(m as *mut libc::c_void);
                            break 'bad;
                        }
                    }
                    'A' => {
                        if strcmp(val, b"ALL\0" as *const u8 as *const libc::c_char)
                            == 0 as libc::c_int
                        {
                            (*m).type0 = ALL as libc::c_int as libc::c_short;
                        } else {
                            (*m).type0 = WORD as libc::c_short;
                            (*m).name = strdup(val);
                            if ((*m).name).is_null() {
                                free(m as *mut libc::c_void);
                                break 'bad;
                            }
                        }
                    }
                    _ => {
                        (*m).type0 = WORD as libc::c_short;
                        (*m).name = strdup(val);
                        if ((*m).name).is_null() {
                            free(m as *mut libc::c_void);
                            break 'bad;
                        }
                    }
                } //end of match

                if (*m).negated != 0 {
                    (*m).entries.tqe_next = std::ptr::null_mut::<member>();
                    (*m).entries.tqe_prev = negated_members.tqh_last;
                    *negated_members.tqh_last = m;
                    negated_members.tqh_last = &mut (*m).entries.tqe_next;
                } else {
                    (*m).entries.tqe_next = std::ptr::null_mut::<member>();
                    (*m).entries.tqe_prev = (*members).tqh_last;
                    *(*members).tqh_last = m;
                    (*members).tqh_last = &mut (*m).entries.tqe_next;
                }
            } //end
              //line 187 189
            if !(negated_members.tqh_first).is_null() {
                *(*members).tqh_last = negated_members.tqh_first;
                (*negated_members.tqh_first).entries.tqe_prev = (*members).tqh_last;
                (*members).tqh_last = negated_members.tqh_last;
                negated_members.tqh_first = std::ptr::null_mut::<member>();
                negated_members.tqh_last = &mut negated_members.tqh_first;
            }
            debug_return_ptr!(members);

            break 'bad;
        } //end of bad

        free_members(&mut negated_members);
        free_members(members);
        free(members as *mut libc::c_void);
        debug_return_ptr!(std::ptr::null_mut::<member_list>());
    } //unsafe
}

#[no_mangle]
fn is_address(mut host: *mut libc::c_char) -> bool {
    let mut addr: sudo_in_addr_un = sudo_in_addr_un {
        ip4: in_addr { s_addr: 0 },
    };
    let mut ret: bool = 0 as libc::c_int != 0;
    let mut slash: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        slash = strchr(host, '/' as i32);
        if !slash.is_null() {
            *slash = '\u{0}' as i32 as libc::c_char;
        }
        if inet_pton(
            AF_INET as libc::c_int,
            host,
            &mut addr.ip4 as *mut in_addr as *mut libc::c_void,
        ) == 1 as libc::c_int
        {
            ret = 1 as libc::c_int != 0;
        } else if inet_pton(
            AF_INET6 as libc::c_int,
            host,
            &mut addr.ip6 as *mut in6_addr as *mut libc::c_void,
        ) == 1 as libc::c_int
        {
            ret = 1 as libc::c_int != 0;
        }

        if !slash.is_null() {
            *slash = '/' as i32 as libc::c_char;
        }
        debug_return_bool!(ret);
    } //unsafe
}

#[no_mangle]
fn host_to_member(mut host: *mut libc::c_char) -> *mut member {
    let mut m: *mut member = std::ptr::null_mut::<member>();
    //let sudo_debug_subsys: libc::c_int = *sudoers_subsystem_ids
    //    .as_mut_ptr()
    //    .offset(6 as libc::c_int as isize) as libc::c_int;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        m = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<member>() as libc::c_ulong,
        ) as *mut member;
        if m.is_null() {
            free(m as *mut libc::c_void);
            debug_return_ptr!(std::ptr::null_mut::<member>());
        }

        (*m).negated = sudo_ldap_is_negated(&mut host) as libc::c_short;
        (*m).name = strdup(host);

        if ((*m).name).is_null() {
            free(m as *mut libc::c_void);
            debug_return_ptr!(std::ptr::null_mut::<member>());
        }

        match *host as u8 as char {
            '+' => {
                (*m).type0 = NETGROUP as libc::c_short;
            }
            'A' => {
                if strcmp(host, b"ALL\0" as *const u8 as *const libc::c_char) == 0 {
                    (*m).type0 = ALL;
                }

                if is_address(host) {
                    (*m).type0 = NTWKADDR as libc::c_short;
                } else {
                    (*m).type0 = WORD as libc::c_short
                }
            }
            _ => {
                if is_address(host) {
                    (*m).type0 = NTWKADDR as libc::c_short;
                } else {
                    (*m).type0 = WORD as libc::c_short
                }
            }
        } //end of match
        debug_return_ptr!(m);
    } //unsafe
}

#[no_mangle]
pub fn sudo_ldap_add_default(
    mut var: *const libc::c_char,
    mut val: *const libc::c_char,
    mut op: libc::c_int,
    mut source: *mut libc::c_char,
    mut defs: *mut defaults_list,
) -> bool {
    let mut def: *mut defaults = std::ptr::null_mut::<defaults>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        'oom: loop {
            def = calloc(
                1 as libc::c_int as libc::c_ulong,
                ::std::mem::size_of::<defaults>() as libc::c_ulong,
            ) as *mut defaults;
            if def.is_null() {
                break 'oom;
            }

            (*def).type_0 = DEFAULTS;
            (*def).op = op as libc::c_char;
            (*def).val = strdup(var);
            if ((*def).var).is_null() {
                break 'oom;
            }
            if !val.is_null() {
                (*def).val = strdup(val);
                if ((*def).val).is_null() {
                    break 'oom;
                }
            }
            (*def).file = source;
            rcstr_addref(source);

            (*def).entries.tqe_next = std::ptr::null_mut::<defaults>();
            (*def).entries.tqe_prev = (*defs).tqh_last;
            *(*defs).tqh_last = def;
            (*defs).tqh_last = &mut (*def).entries.tqe_next;

            debug_return_bool!(true);

            break 'oom;
        }
        if !def.is_null() {
            free((*def).var as *mut libc::c_void);
            free((*def).val as *mut libc::c_void);
            free(def as *mut libc::c_void);
        }
        debug_return_bool!(false);
    } //unsafe
}

#[no_mangle]
pub fn sudo_ldap_role_to_priv(
    mut cn: *const libc::c_char,
    mut hosts: *mut libc::c_void,
    mut runasusers: *mut libc::c_void,
    mut runasgroups: *mut libc::c_void,
    mut cmnds: *mut libc::c_void,
    mut opts: *mut libc::c_void,
    mut notbefore: *const libc::c_char,
    mut notafter: *const libc::c_char,
    mut warnings: bool,
    mut store_options: bool,
    mut iter: sudo_ldap_iter_t,
) -> *mut privilege {
    let mut negated_cmnds: cmndspec_list = cmndspec_list {
        tqh_first: std::ptr::null_mut::<cmndspec>(),
        tqh_last: std::ptr::null_mut::<*mut cmndspec>(),
    };
    negated_cmnds = {
        cmndspec_list {
            tqh_first: std::ptr::null_mut::<cmndspec>(),
            tqh_last: &mut negated_cmnds.tqh_first,
        }
        //init
    };
    let mut negated_hosts: member_list = member_list {
        tqh_first: std::ptr::null_mut::<member>(),
        tqh_last: std::ptr::null_mut::<*mut member>(),
    };
    negated_hosts = {
        member_list {
            tqh_first: std::ptr::null_mut::<member>(),
            tqh_last: &mut negated_hosts.tqh_first,
        }
        //init
    };
    let mut prev_cmndspec: *mut cmndspec = std::ptr::null_mut::<cmndspec>();
    let mut priv_0: *mut privilege = std::ptr::null_mut::<privilege>();
    let mut m: *mut member = std::ptr::null_mut::<member>();
    let mut cmnd: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        'oom: loop {
            priv_0 = calloc(
                1 as libc::c_int as libc::c_ulong,
                ::std::mem::size_of::<privilege>() as libc::c_ulong,
            ) as *mut privilege;
            if priv_0.is_null() {
                break 'oom;
            }
            (*priv_0).hostlist.tqh_first = std::ptr::null_mut::<member>();
            (*priv_0).hostlist.tqh_last = &mut (*priv_0).hostlist.tqh_first;

            (*priv_0).cmndlist.tqh_first = std::ptr::null_mut::<cmndspec>();
            (*priv_0).cmndlist.tqh_last = &mut (*priv_0).cmndlist.tqh_first;

            (*priv_0).defaults.tqh_first = std::ptr::null_mut::<defaults>();
            (*priv_0).defaults.tqh_last = &mut (*priv_0).defaults.tqh_first;

            (*priv_0).ldap_role = strdup(if !cn.is_null() {
                cn
            } else {
                b"UNKNOWN\0" as *const u8 as *const libc::c_char
            });
            if ((*priv_0).ldap_role).is_null() {
                break 'oom;
            }

            if hosts.is_null() {
                m = calloc(
                    1 as libc::c_int as libc::c_ulong,
                    ::std::mem::size_of::<member>() as libc::c_ulong,
                ) as *mut member;
                if m.is_null() {
                    break 'oom;
                }
                (*m).type0 = ALL;
                (*m).entries.tqe_next = std::ptr::null_mut::<member>();
                (*m).entries.tqe_prev = (*priv_0).hostlist.tqh_last;
                *(*priv_0).hostlist.tqh_last = m;
                (*priv_0).hostlist.tqh_last = &mut (*m).entries.tqe_next;
            } else {
                let mut host: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
                loop {
                    host = iter.expect("non-null function pointer")(&mut hosts);
                    if host.is_null() {
                        break;
                    }
                    m = host_to_member(host);
                    if m.is_null() {
                        break 'oom;
                    }
                    if (*m).negated != 0 {
                        (*m).entries.tqe_next = std::ptr::null_mut::<member>();
                        (*m).entries.tqe_prev = negated_hosts.tqh_last;
                        *negated_hosts.tqh_last = m;
                        negated_hosts.tqh_last = &mut (*m).entries.tqe_next;
                    } else {
                        (*m).entries.tqe_next = std::ptr::null_mut::<member>();
                        (*m).entries.tqe_prev = (*priv_0).hostlist.tqh_last;
                        *(*priv_0).hostlist.tqh_last = m;
                        (*priv_0).hostlist.tqh_last = &mut (*m).entries.tqe_next;
                    }
                }
                if !(negated_hosts.tqh_first).is_null() {
                    *(*priv_0).hostlist.tqh_last = negated_hosts.tqh_first;
                    (*negated_hosts.tqh_first).entries.tqe_prev = (*priv_0).hostlist.tqh_last;
                    (*priv_0).hostlist.tqh_last = negated_hosts.tqh_last;
                    negated_hosts.tqh_first = std::ptr::null_mut::<member>();
                    negated_hosts.tqh_last = &mut negated_hosts.tqh_first;
                }
            }

            loop {
                cmnd = iter.expect("non-null function pointer")(&mut cmnds);
                if cmnd.is_null() {
                    break;
                }
                let mut negated: bool = sudo_ldap_is_negated(&mut cmnd);
                let mut c: *mut sudo_command = std::ptr::null_mut::<sudo_command>();
                let mut cmndspec: *mut cmndspec = std::ptr::null_mut::<cmndspec>();

                cmndspec = calloc(
                    1 as libc::c_int as libc::c_ulong,
                    ::std::mem::size_of::<cmndspec>() as libc::c_ulong,
                ) as *mut cmndspec;
                if cmndspec.is_null() {
                    break 'oom;
                }
                m = calloc(
                    1 as libc::c_int as libc::c_ulong,
                    ::std::mem::size_of::<member>() as libc::c_ulong,
                ) as *mut member;
                if m.is_null() {
                    free(cmndspec as *mut libc::c_void);
                    break 'oom;
                }

                if strcmp(cmnd, b"ALL\0" as *const u8 as *const libc::c_char) != 0 as libc::c_int {
                    c = calloc(
                        1 as libc::c_int as libc::c_ulong,
                        ::std::mem::size_of::<sudo_command>() as libc::c_ulong,
                    ) as *mut sudo_command;
                    if c.is_null() {
                        free(cmndspec as *mut libc::c_void);
                        free(m as *mut libc::c_void);
                        break 'oom;
                    }
                    (*m).name = c as *mut libc::c_char;
                }

                if negated {
                    (*cmndspec).entries.tqe_next = std::ptr::null_mut::<cmndspec>();
                    (*cmndspec).entries.tqe_prev = negated_cmnds.tqh_last;
                    *negated_cmnds.tqh_last = cmndspec;
                    negated_cmnds.tqh_last = &mut (*cmndspec).entries.tqe_next;
                } else {
                    (*cmndspec).entries.tqe_next = std::ptr::null_mut::<cmndspec>();
                    (*cmndspec).entries.tqe_prev = (*priv_0).cmndlist.tqh_last;
                    *(*priv_0).cmndlist.tqh_last = cmndspec;
                    (*priv_0).cmndlist.tqh_last = &mut (*cmndspec).entries.tqe_next;
                }

                let fresh49 = &mut (*cmndspec).tags;
                (*fresh49).set_follow(-(1 as libc::c_int));
                let fresh50 = &mut (*cmndspec).tags;
                (*fresh50).set_log_input(-(1 as libc::c_int));
                let fresh51 = &mut (*cmndspec).tags;
                (*fresh51).set_log_output(-(1 as libc::c_int));
                let fresh52 = &mut (*cmndspec).tags;
                (*fresh52).set_noexec(-(1 as libc::c_int));
                let fresh53 = &mut (*cmndspec).tags;
                (*fresh53).set_nopasswd(-(1 as libc::c_int));
                let fresh54 = &mut (*cmndspec).tags;
                (*fresh54).set_send_mail(-(1 as libc::c_int));
                let fresh55 = &mut (*cmndspec).tags;
                (*fresh55).set_setenv(-(1 as libc::c_int));
                (*cmndspec).notbefore = -(1 as libc::c_int) as time_t;
                (*cmndspec).notafter = -(1 as libc::c_int) as time_t;
                (*cmndspec).timeout = -(1 as libc::c_int);
                let fresh56 = &mut (*cmndspec).cmnd;
                *fresh56 = m;

                if !prev_cmndspec.is_null() {
                    (*cmndspec).runasuserlist = (*prev_cmndspec).runasuserlist;
                    (*cmndspec).runasgrouplist = (*prev_cmndspec).runasgrouplist;
                    (*cmndspec).notbefore = (*prev_cmndspec).notbefore;
                    (*cmndspec).notafter = (*prev_cmndspec).notafter;
                    (*cmndspec).tags = (*prev_cmndspec).tags;
                    if ((*cmndspec).tags).setenv() == IMPLIED as libc::c_int {
                        let fresh59 = &mut (*cmndspec).tags;
                        (*fresh59).set_setenv(UNSPEC);
                    }
                } else {
                    if !runasusers.is_null() {
                        (*cmndspec).runasuserlist = array_to_member_list(runasusers, iter);
                        if ((*cmndspec).runasuserlist).is_null() {
                            break 'oom;
                        }
                    }

                    if !runasgroups.is_null() {
                        (*cmndspec).runasgrouplist = array_to_member_list(runasgroups, iter);
                        if ((*cmndspec).runasgrouplist).is_null() {
                            break 'oom;
                        }
                    }

                    if !notbefore.is_null() {
                        (*cmndspec).notbefore = parse_gentime(notbefore);
                    }
                    if !notafter.is_null() {
                        (*cmndspec).notafter = parse_gentime(notafter);
                    }

                    if !opts.is_null() {
                        let mut opt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
                        let mut source: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();

                        if store_options {
                            let mut slen: size_t = (::std::mem::size_of::<[libc::c_char; 9]>()
                                as libc::c_ulong)
                                .wrapping_add(strlen((*priv_0).ldap_role));
                            source = rcstr_alloc(slen);
                            if source.is_null() {
                                break 'oom;
                            }
                            snprintf(
                                source,
                                slen,
                                b"sudoRole %s\0" as *const u8 as *const libc::c_char,
                                (*priv_0).ldap_role,
                            );
                        }

                        loop {
                            opt = iter.expect("non-null function pointer")(&mut opts);
                            if opt.is_null() {
                                break;
                            }
                            let mut var: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
                            let mut val: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
                            let mut op: libc::c_int = 0;
                            op = sudo_ldap_parse_option(opt, &mut var, &mut val);

                            if strcmp(
                                var,
                                b"command_timeout\0" as *const u8 as *const libc::c_char,
                            ) == 0 as libc::c_int
                                && !val.is_null()
                            {
                                (*cmndspec).timeout = parse_timeout(val);
                            } else if strcmp(var, b"role\0" as *const u8 as *const libc::c_char)
                                == 0 as libc::c_int
                                && !val.is_null()
                            {
                                (*cmndspec).role = strdup(val);
                                if ((*cmndspec).role).is_null() {
                                    break;
                                }
                            } else if strcmp(var, b"type\0" as *const u8 as *const libc::c_char)
                                == 0 as libc::c_int
                                && !val.is_null()
                            {
                                (*cmndspec).type_0 = strdup(val);
                                if ((*cmndspec).type_0).is_null() {
                                    break;
                                }
                            } else if store_options {
                                if !sudo_ldap_add_default(
                                    var,
                                    val,
                                    op,
                                    source,
                                    &mut (*priv_0).defaults,
                                ) {
                                    break;
                                }
                            } else {
                                let mut converted: bool =
                                    sudoers_defaults_to_tags(var, val, op, &mut (*cmndspec).tags);
                                if !converted {
                                    if warnings {
                                        if !val.is_null() {
                                            sudo_warnx!(
                                                b"unable to convert sudoOption: %s%s%s\0"
                                                    as *const u8
                                                    as *const libc::c_char,
                                                var,
                                                if op == '+' as i32 {
                                                    b"+=\0" as *const u8 as *const libc::c_char
                                                } else if op == '-' as i32 {
                                                    b"-=\0" as *const u8 as *const libc::c_char
                                                } else {
                                                    b"=\0" as *const u8 as *const libc::c_char
                                                },
                                                val
                                            );
                                        } else {
                                            sudo_warnx!(
                                                b"unable to convert sudoOption: %s%s%s\0"
                                                    as *const u8
                                                    as *const libc::c_char,
                                                if op == 0 as libc::c_int {
                                                    b"!\0" as *const u8 as *const libc::c_char
                                                } else {
                                                    b"\0" as *const u8 as *const libc::c_char
                                                },
                                                var,
                                                b"\0" as *const u8 as *const libc::c_char
                                            );
                                        }
                                    }
                                    continue;
                                }
                            }
                        } //end of loop
                        rcstr_delref(source);
                        if !opt.is_null() {
                            break 'oom;
                        }
                    } //end of !opts.is_null

                    prev_cmndspec = cmndspec;
                } //end of else

                (*m).negated = negated as libc::c_short;
                if c.is_null() {
                    (*m).type0 = ALL;
                    if ((*cmndspec).tags).setenv() == -(1 as libc::c_int) {
                        let fresh64 = &mut (*cmndspec).tags;
                        (*fresh64).set_setenv(IMPLIED as libc::c_int);
                    }
                } else {
                    let mut digest: command_digest = command_digest {
                        digest_type: 0,
                        digest_str: std::ptr::null_mut::<libc::c_char>(),
                    };
                    let mut args: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
                    (*m).type0 = COMMAND as libc::c_int as libc::c_short;
                    if !(sudo_ldap_extract_digest(&mut cmnd, &mut digest)).is_null() {
                        (*c).digest =
                            malloc(::std::mem::size_of::<command_digest>() as libc::c_ulong)
                                as *mut command_digest;
                        if ((*c).digest).is_null() {
                            break 'oom;
                        }
                        *(*c).digest = digest;
                    }
                    args = strpbrk(cmnd, b" \t\0" as *const u8 as *const libc::c_char);
                    if !args.is_null() {
                        let fresh66 = args;
                        args = args.offset(1);
                        *fresh66 = '\u{0}' as i32 as libc::c_char;
                        let fresh67 = &mut (*c).args;
                        *fresh67 = strdup(args);
                        if (*fresh67).is_null() {
                            break 'oom;
                        }
                    }
                    (*c).cmnd = strdup(cmnd);
                    if ((*c).cmnd).is_null() {
                        break 'oom;
                    }
                }
            } //end of long loop

            if !(negated_cmnds.tqh_first).is_null() {
                *(*priv_0).cmndlist.tqh_last = negated_cmnds.tqh_first;
                (*negated_cmnds.tqh_first).entries.tqe_prev = (*priv_0).cmndlist.tqh_last;
                (*priv_0).cmndlist.tqh_last = negated_cmnds.tqh_last;
                negated_cmnds.tqh_first = std::ptr::null_mut::<cmndspec>();
                negated_cmnds.tqh_last = &mut negated_cmnds.tqh_first;
            }
            debug_return_ptr!(priv_0);
            break 'oom;
        } //end of goto oom;
        sudo_warnx!(
            b"%s: %s\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            b"unable to allocate memory\0" as *const u8 as *const libc::c_char
        );
        if !priv_0.is_null() {
            if !(negated_hosts.tqh_first).is_null() {
                *(*priv_0).hostlist.tqh_last = negated_hosts.tqh_first;
                (*negated_hosts.tqh_first).entries.tqe_prev = (*priv_0).hostlist.tqh_last;
                (*priv_0).hostlist.tqh_last = negated_hosts.tqh_last;
                negated_hosts.tqh_first = std::ptr::null_mut::<member>();
                negated_hosts.tqh_last = &mut negated_hosts.tqh_first;
            }
            if !(negated_cmnds.tqh_first).is_null() {
                *(*priv_0).cmndlist.tqh_last = negated_cmnds.tqh_first;
                (*negated_cmnds.tqh_first).entries.tqe_prev = (*priv_0).cmndlist.tqh_last;
                (*priv_0).cmndlist.tqh_last = negated_cmnds.tqh_last;
                negated_cmnds.tqh_first = std::ptr::null_mut::<cmndspec>();
                negated_cmnds.tqh_last = &mut negated_cmnds.tqh_first;
            }
            free_privilege(priv_0);
        }
        debug_return_ptr!(std::ptr::null_mut::<privilege>());
    } //unsafe
}

#[no_mangle]
pub fn sudo_ldap_extract_digest(
    mut cmnd: *mut *mut libc::c_char,
    mut digest: *mut command_digest,
) -> *mut command_digest {
    let mut ep: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    unsafe {
        let mut cp: *mut libc::c_char = *cmnd;
        let mut digest_type: libc::c_int = 4 as libc::c_int;
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        if *cp.offset(0 as libc::c_int as isize) as libc::c_int == 's' as i32
            && *cp.offset(1 as libc::c_int as isize) as libc::c_int == 'h' as i32
            && *cp.offset(2 as libc::c_int as isize) as libc::c_int == 'a' as i32
        {
            match *cp.offset(3 as libc::c_int as isize) as libc::c_int as u8 as char {
                '2' => {
                    if *cp.offset(4 as libc::c_int as isize) as libc::c_int == '2' as i32
                        && *cp.offset(5 as libc::c_int as isize) as libc::c_int == '4' as i32
                    {
                        digest_type = SUDO_DIGEST_SHA224 as libc::c_int;
                    } else if *cp.offset(4 as libc::c_int as isize) as libc::c_int == '5' as i32
                        && *cp.offset(5 as libc::c_int as isize) as libc::c_int == '6' as i32
                    {
                        digest_type = SUDO_DIGEST_SHA256 as libc::c_int;
                    }
                }
                '3' => {
                    if *cp.offset(4 as libc::c_int as isize) as libc::c_int == '8' as i32
                        && *cp.offset(5 as libc::c_int as isize) as libc::c_int == '4' as i32
                    {
                        digest_type = SUDO_DIGEST_SHA384 as libc::c_int;
                    }
                }
                '5' => {
                    if *cp.offset(4 as libc::c_int as isize) as libc::c_int == '1' as i32
                        && *cp.offset(5 as libc::c_int as isize) as libc::c_int == '2' as i32
                    {
                        digest_type = SUDO_DIGEST_SHA512 as libc::c_int;
                    }
                }
                _ => {}
            }

            if digest_type != SUDO_DIGEST_INVALID as libc::c_int {
                cp = cp.offset(6 as libc::c_int as isize);
                while *(*__ctype_b_loc()).offset(*cp as libc::c_uchar as libc::c_int as isize)
                    as libc::c_int
                    & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                    != 0
                {
                    cp = cp.offset(1);
                }
                if *cp as libc::c_int == ':' as i32 {
                    cp = cp.offset(1);
                    while *(*__ctype_b_loc()).offset(*cp as libc::c_uchar as libc::c_int as isize)
                        as libc::c_int
                        & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                        != 0
                    {
                        cp = cp.offset(1);
                    }
                    ep = cp;
                    while *ep as libc::c_int != '\u{0}' as i32
                        && *(*__ctype_b_loc()).offset(*ep as libc::c_uchar as libc::c_int as isize)
                            as libc::c_int
                            & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                            == 0
                    {
                        ep = ep.offset(1);
                    }

                    if *ep as libc::c_int != '\u{0}' as i32 {
                        (*digest).digest_type = digest_type as libc::c_uint;
                        (*digest).digest_str =
                            strndup(cp, ep.offset_from(cp) as libc::c_long as size_t);
                        if ((*digest).digest_str).is_null() {
                            sudo_warnx!(
                                b"%s: %s\0" as *const u8 as *const libc::c_char,
                                get_function_name!(),
                                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                            );
                            debug_return_ptr!(std::ptr::null_mut::<command_digest>());
                        }
                        cp = ep.offset(1 as libc::c_int as isize);
                        while *(*__ctype_b_loc())
                            .offset(*cp as libc::c_uchar as libc::c_int as isize)
                            as libc::c_int
                            & _ISblank as libc::c_int as libc::c_ushort as libc::c_int
                            != 0
                        {
                            cp = cp.offset(1);
                        }
                        *cmnd = cp;
                        sudo_debug_printf!(
                            SUDO_DEBUG_INFO,
                            b"%s digeest %s for %s\0" as *const u8 as *const libc::c_char,
                            digest_type_to_name(digest_type),
                            (*digest).digest_str,
                            cp
                        );
                        debug_return_ptr!(digest);
                    }
                }
            }
        }
        debug_return_ptr!(std::ptr::null_mut::<command_digest>());
    } //unsafe
}
